<?php
/*
This file is part of Authake.

Author: Jérôme Combaz (jakecake/velay.greta.fr)
Contributors:

Authake is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Authake is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
*/

App::uses('CakeEmail', 'Network/Email');
class UserController extends AuthakeAppController {
	var $uses     = array('Authake.User', 'Authake.Rule', 'Authake.Group');
	var $components = array('Email');
	//var $layout = 'authake';

	//var $scaffold;

	function denied(){
		// display this view (/app/views/users/denied.ctp) when the user is denied
	}

	function message(){
		// display this view if you want to say something important to your users.
		// For example (your password was changed and you need to receive mail to
			// confirm it.)
		}

		/**
		* User profile
		*/
	function index() {
		if (!$this->Authake->getUserId()) {
			$this->Session->setFlash(__('Неверный пользователь'), 'error', array('plugin' => 'Authake'));
			$this->redirect('/');
		}

		$this->User->recursive = 1;

		$user = $this->User->read(null, $this->Authake->getUserId());

		if (!empty($this->request->data)) {
			if ($this->request->data['User']['password1'] != '') { // password changed
				if ($this->request->data['User']['password1'] != $this->request->data['User']['password2']) {
					$this->Session->setFlash(__('Два пароля не совпадают!'), 'error', array('plugin' => 'Authake'));
				} else {
					$user['User']['password'] = md5($this->request->data['User']['password1']);
					$this->Session->setFlash(__('Пароль изменен!'), 'success', array('plugin' => 'Authake'));
				}
			}
			$state = 0;
			if (Configure::read('Authake.passwordVerify') == true && $this->request->data['User']['email'] != $user['User']['email']) {
				//Check if that email is not registered by another user
				if($this->User->find('count', array('conditions'=>array('User.email LIKE'=>$this->request->data['User']['email'], 'User.id != '.$user['User']['id']))) > 0){
					$this->Session->setFlash(__('Эта электронная почта используется другим пользователем в системе. Пожалуйста, попробуйте другой!'), 'error', array('plugin' => 'Authake'));
					$this->redirect(array('action'=>'index'));
				}

				$user['User']['emailcheckcode'] = md5(rand().time().rand().$user['User']['email']);
				$user['User']['email'] = $this->request->data['User']['email'];
				// send a mail with code to change the pw
				$email = new CakeEmail();
				$email->to($user['User']['email']);
				$email->subject(sprintf(__('Запрос на изменение почты на %s '), Configure::read('Authake.service', 'Authentication')));
				$email->replyTo(Configure::read('Authake.systemReplyTo'));
				$email->from(Configure::read('Authake.systemEmail'));
				$email->emailFormat('html');
				//$this->Email->charset = 'utf-8';
				$email->template('Authake.verify');
				//Set the code into template
				$this->set('code', $user['User']['emailcheckcode']);
				$this->set('service', Configure::read('Authake.service'));
				if ($email->send() ) {
					$state = 1;
				} else {
					$state = 2;
				}
			}

			//Unbind HABTM relation for this save
			$this->User->unbindModel(array('hasAndBelongsToMany'=>array('Group')), false);

			if($this->User->save($user['User'])){

				switch($state){
					case 1:
					$this->Session->setFlash(__('Ваш адрес электронной почты был изменен, вы должны получить письмо с инструкциями, чтобы подтвердить свой новый адрес электронной почты...'), 'warning', array('plugin' => 'Authake'));
					break;

					case 2:
					$this->Session->setFlash(sprintf(__('Невозможно отправить электронную почту для изменения пароля. Пожалуйста, свяжитесь с администратором %s'), Configure::read('Authake.systemReplyTo')), 'error', array('plugin' => 'Authake'));
					break;
					default:
					$this->Session->setFlash(__('Профиль пользователя был сохранен'), 'success', array('plugin' => 'Authake'));
				}
			}
			if(Configure::read('Authake.passwordVerify') == true){
				$this->redirect(array('action'=>'index'));
			} else {
				$this->redirect(array('action'=>'messages'));
			}
		}

		//$this->request->data = null;
		$this->set(compact('user'));
	}

	/**
	* Confirm the email change if needed
	*/
function verify($code = null) {
	if(Configure::read('Authake.registration') == false){
		$this->redirect('/');
	}

	if($code != null){
		$this->request->data['User']['code'] = $code;
	}
	if (!empty($this->request->data)) {
		$this->User->recursive = 0;
		$user = $this->User->find('first', array('conditions'=>array('emailcheckcode'=>$this->request->data['User']['code'])));

		if (empty($user)) { // bad code or email
			$this->Session->setFlash(__('Плохие идентификационные данные!'), 'error', array('plugin' => 'Authake'));
		} else {
			$user['User']['emailcheckcode'] = '';
			$this->User->unbindModel(array('hasAndBelongsToMany'=>array('Group')), false);
			$this->User->save($user);

			if($this->Authake->getUserId() == null){ //User need to be redirected to login
				$this->Session->setFlash(__('Код подтверждения был принят. Вы можете войти в систему!'), 'success', array('plugin' => 'Authake'));
				$this->redirect(array('action'=>'login'));
			} else {
				$this->Session->setFlash(__('Код подтверждения был принят. Спасибо!'), 'success', array('plugin' => 'Authake'));
				$this->redirect(array('action'=>'index'));
			}
		}
	}
}

/**
* User registration
*/
function register() {
	if(Configure::read('Authake.registration') == false){
		$this->redirect('/');
	}
	if (!empty($this->request->data)) {

		$this->User->recursive = 0;
		/* If settings say we should use only email info instead of username/email, skip this */
		if(Configure::read('Authake.useEmailAsUsername') == false){
			$exist = $this->User->findByLogin($this->request->data['User']['login']);
			if (!empty($exist)) {
				$this->Session->setFlash(__('Это имя уже используется!'), 'error', array('plugin' => 'Authake'));
				return;
			}

			$exist = $this->User->findByEmail($this->request->data['User']['email']);
			if (!empty($exist)) {
				$this->Session->setFlash(__('Этот адрес уже зарегистрирован!'), 'error', array('plugin' => 'Authake'));
				return;
			}

			$pwd = $this->__makePassword($this->request->data['User']['password1'], $this->request->data['User']['password2']);
			if (!$pwd) return;  // password is invalid...
			$this->request->data['User']['password'] = $pwd;

			$this->request->data['User']['emailcheckcode'] = md5(time()*rand());
			$this->User->create();
			//add default group if there is such thing
			if(Configure::read('Authake.defaultGroup') != null && Configure::read('Authake.defaultGroup') != false){
				$groups = $this->Group->find('all', array('fields'=>array('Group.id'), 'conditions'=>array('Group.id'=>Configure::read('Authake.defaultGroup'))));
				foreach($groups as $group){
					$this->request->data['Group']['Group'][] = $group['Group']['id'];
				}
			}
			//
			if ($this->User->save($this->request->data)) {

				// send a mail to finish the registration
				$email = new CakeEmail();
				$email->to($this->request->data['User']['email']);
				$email->subject(sprintf(__('Ваше подтверждение регистрации в %s '), Configure::read('Authake.service', 'Authentication')));

				$email->viewVars(array('service' => Configure::read('Authake.service'), 'code'=> $this->request->data['User']['emailcheckcode']));
				$email->replyTo(Configure::read('Authake.systemReplyTo'));
				$email->from(Configure::read('Authake.systemEmail'));
				$email->emailFormat('html');
				//$this->Email->charset = 'utf-8';
				$email->template('Authake.register');
				//Set the code into template
				//$this->set('code', $this->request->data['User']['emailcheckcode']);
				//$this->set('service', Configure::read('Authake.service'));

				if ($email->send()) {
					$this->Session->setFlash(__('Вы получите письмо с кодом для завершения регистрации...'), 'info', array('plugin' => 'Authake'));
				} else {
					$this->Session->setFlash(sprintf(__('Не удалось отправить электронное письмо с подтверждением. Пожалуйста, свяжитесь с администратором %s'), Configure::read('Authake.systemReplyTo')), 'error', array('plugin' => 'Authake'));
				}
				$this->redirect(array('plugin'=>'authake','controller'=>'user','action'=>'login'));
			} else {
				$this->Session->setFlash(__('Не удалось зарегистрировать!'), 'error', array('plugin' => 'Authake'));
			}
		}
	}
}
	/**
	* Function which allow user to change his password if he request it
	*/
function pass($code = null){
	if($this->Authake->getUserId() > 0){
		$this->Session->setFlash(__('Вы уже вошли. Проверьте пароль в профиле!'), 'warning', array('plugin' => 'Authake'));
		$this->redirect(array('action'=>'index'));
	}
	$this->User->recursive = 0;
	if (!empty($this->request->data)) {
		$user = $this->User->find('first', array('conditions'=>array('passwordchangecode'=>$this->request->data['User']['passwordchangecode'])));
		if (!empty($user)) {
			$pwd = $this->__makePassword($this->request->data['User']['password1'], $this->request->data['User']['password2']);
			if (!$pwd) return;  // password is invalid...

			$user['User']['password'] = $pwd;
			$user['User']['passwordchangecode'] = '';
			$this->User->unbindModel(array('hasAndBelongsToMany'=>array('Group')), false);
			if($this->User->save($user)){
				//
				$this->Session->setFlash(__('Ваш пароль был изменен. Вы можете войти в систему!'), 'success', array('plugin' => 'Authake'));
				$this->redirect(array('action'=>'login'));
			} else {
				$this->Session->setFlash(__('Ошибка при сохранении пароля!'), 'error', array('plugin' => 'Authake'));
			}
		}
	}
	if($code != null){
		$this->request->data['User']['passwordchangecode'] = $code;
	}
}

/**
* Login functionality
*/
function login(){
	if ($this->Authake->isLogged()) {
		$this->Session->setFlash(__('Вы уже вошли в систему!'), 'info', array('plugin' => 'Authake'));
		$this->redirect(Configure::read('Authake.loggedAction'));
	}

	if (!empty($this->request->data) ) {
		$login  = $this->request->data['User']['login'];
		$password = $this->request->data['User']['password'];

		if(Configure::read('Authake.useEmailAsUsername') == false){
			$user = $this->User->findByLogin($login);
		} else {
			$user = $this->User->findByEmail($login);
		}

		if (empty($user)) {
			$this->Session->setFlash(__('Неверный логин или пароль!'), 'error', array('plugin' => 'Authake'));
			return;
		}

		// check for locked account
		if ($user['User']['id'] != 1 and $user['User']['disable']) {
			$this->Session->setFlash(__('Ваша учетная запись отключена!'), 'error', array('plugin' => 'Authake'));
			$this->redirect('/');
		}

		// check for expired account
		$exp = $user['User']['expire_account'];
		if ($user['User']['id'] != 1 and $exp != '0000-00-00' and $exp != null and strtotime($exp) < time()) {
			$this->Session->setFlash(__('Ваша учетная запись дезактивирована!'), 'error', array('plugin' => 'Authake'));
			$this->redirect('/');
		}

		// check for not confirmed email
		if ($user['User']['emailcheckcode'] != '') {
			$this->Session->setFlash(__('Ваша регистрация не была подтверждена!'), 'warning', array('plugin' => 'Authake'));
			$this->redirect(array('action'=>'verify'));
		}

		$userdata = $this->User->getLoginData($login, $password);

		if (empty($userdata)) {
			$this->Session->setFlash(__('Неверный логин или пароль!'), 'error', array('plugin' => 'Authake'));
			return;
		} else {
			if($user['User']['passwordchangecode'] != ''){
				//clear password change code (if there is any)
				$this->User->unbindModel(array('hasAndBelongsToMany'=>array('Group')), false);
				$user['User']['passwordchangecode'] = '';
				$this->User->save($user);
			}

			$this->Authake->login($userdata['User']);
			//debug($userdata['User']/* ['login'] */);
			
			// читаем к каким группам относится пользователь
			$groups = $userdata['User']['group_names'];
			$session_groups = '';
			foreach ($groups as $group):
				$session_groups .= $group.' ';
			endforeach;
			
			$this->Session->setFlash(__('Вы вошли как ').$userdata['User']['login'], 'success' , array('plugin'=>'authake'));
			
			
			// создаем новую переменную сессии для ведения log
			
			$newLogsSettings = $userdata['User']['login'].'|'.$session_groups;
			$this->Session->write('LogsSettings', $newLogsSettings);
			
			
			$nowtime = date('Y-m-d H:i:s');
			$year = date('Y');
			$month = date('m');
			$day = date('d');
			$hour = date('H');
			$minutes = date('i');
			$seconds = date('s');
			
			if (($minutes - 10)<0){
				if (($hour - 1)<0){
					$hour = 23;
				} else {
					$hour -= 1;
				}
				$minutes = 60 - (10 - $minutes);
			} else {
				if ($minutes <20){
					$minutes = '0'.($minutes-10);
				} else {
					$minutes -= 10;
				}
			}
			$cleartime = $year.'-'.$month.'-'.$day.' '.$hour.':'.$minutes.':'.$seconds;

			// подключаем модель Onlineuser
			$this->loadModel('Onlineuser');
			// удаляем тех пользователей последнее действие которых было более 10 минут назад
			$this->Onlineuser->deleteall(array('Onlineuser.lastaction <' => $cleartime), false);
			//записываем в таблицу Onlineuser запись о новом пользователе online
			$this->Onlineuser->create();
			$activeuser = array('Onlineuser' => array('login' => $userdata['User']['login'], 'lastaction' => $nowtime));
			$this->Onlineuser->save($activeuser);
			
			if (($next = $this->Authake->getPreviousUrl()) !== null) {
				$this->redirect($next);
			} else {
				$this->redirect(Configure::read('Authake.loggedAction'));
			}
			
		}
	}
}

function lost_password() {
	if(Configure::read('Authake.registration') == false){
		$this->redirect('/');
	}
	$this->User->recursive = 0;

	if (!empty($this->request->data)) {
		$loginoremail = $this->request->data['User']['loginoremail'];
		if ($loginoremail) {
			$user = $this->User->findByLogin($loginoremail);
		}
		if (empty($user)) {
			$user = $this->User->findByEmail($loginoremail);
		}
		if (!empty($user)) { // ok, login or email is ok
			//Prevent sending more than 11 e-mail
			if($user['User']['passwordchangecode'] != ''){
				$this->Session->setFlash(__("Вы уже просили изменить пароль. Пожалуйста, проверьте вашу электронную почту и использовать код, который мы послали"), 'error', array('plugin' => 'Authake'));
				$this->redirect(array('action'=>'lost_password'));
			}
			$md5 = $user['User']['passwordchangecode'] = md5(time()*rand().$user['User']['email']);

			$this->User->unbindModel(array('hasAndBelongsToMany'=>array('Group')), false);
			if ($this->User->save($user)) {
				// send a mail with code to change the pw
				$this->Email->to = $user['User']['email'];
				$this->Email->subject = sprintf(__('Изменение Вашего пароля запрос на %s '), Configure::read('Authake.service', 'Authentication'));
				$this->Email->replyTo = Configure::read('Authake.systemReplyTo');
				$this->Email->from = Configure::read('Authake.systemEmail');
				$this->Email->sendAs = 'html';
				$this->Email->charset = 'utf-8';
				$this->Email->template = 'Authake.lost_password';
				//Set the code into template
				$this->set('code', $user['User']['passwordchangecode']);
				$this->set('service', Configure::read('Authake.service'));

				if ($this->Email->send() ) {
					$this->Session->setFlash(__('Если данные верны, вы должны получить письмо с инструкциями для изменения пароля...'), 'warning', array('plugin' => 'Authake'));
				} else {
					$this->Session->setFlash(sprintf(__('Невозможно отправить электронную почту для изменения пароля. Пожалуйста, свяжитесь с администратором %s'), Configure::read('Authake.systemReplyTo')), 'error', array('plugin' => 'Authake'));
				}
			} else {
				$this->Session->setFlash(sprintf(__('Не удалось изменить пароль. Пожалуйста, свяжитесь с администратором %s'), Configure::read('Authake.systemReplyTo')), 'error', array('plugin' => 'Authake'));
			}
		} else {
			$this->Session->setFlash(__('Если данные верны, вы должны получить письмо с инструкциями для изменения пароля...'), 'warning', array('plugin' => 'Authake'));
		}
		$this->redirect(array('action'=>'lost_password'));
	}
}

function logout()
{
	if ($this->Authake->isLogged()) {
		
		// получаем время инактивности
		$year = date('Y');
		$month = date('m');
		$day = date('d');
		$hour = date('H');
		$minutes = date('i');
		$seconds = date('s');
			
		if (($minutes - 10)<0){
			if (($hour - 1)<0){
				$hour = 23;
			} else {
				$hour -= 1;
			}
			$minutes = 60 - (10 - $minutes);
		} else {
			if ($minutes <20){
				$minutes = '0'.($minutes-10);
			} else {
				$minutes -= 10;
			}
		}
		$cleartime = $year.'-'.$month.'-'.$day.' '.$hour.':'.$minutes.':'.$seconds;

		// подключаем модель Onlineuser
		$this->loadModel('Onlineuser');
		// удаляем тех пользователей последнее действие которых было более 10 минут назад
		$this->Onlineuser->deleteall(array('Onlineuser.lastaction <' => $cleartime), false);
		$logsettings = explode('|', $this->Session->read('LogsSettings'));
		// удаляем пользователя который выходит
		$this->Onlineuser->deleteall(array('Onlineuser.login' => $logsettings[0]), false);
		$this->Authake->logout();
		$this->Session->setFlash(__('Вы вышли!'), 'info', array('plugin' => 'Authake'));
	}
	$this->redirect('/');
}

function beforeFilter(){

	parent::beforeFilter();

	//Overwriting the authake layout with the default one
	if(Configure::read('Authake.useDefaultLayout') == true){
		$this->layout = 'default';
	}
}
}


?>